﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using XRpgLibrary.TileEngine;

namespace XRpgLibrary.FadeClasses
{
    public enum VisibilityState
    {
        Visible,
        Invisible,
        PartiallyVisible
    }

    public class Fade : DrawableGameComponent, IGameDrawableMenu, IGameUpdateableMenu
    {
        private Color FadeColor;
        private RpgGame game;
        private Rectangle screenRect;
        private float opacity;
        private int fadeDirection = 0;
        private float fadeTime = -1;

        private Texture2D fadeTexture = null;
        private Texture2D FadeTexture
        {
            get
            {
                if (fadeTexture == null)
                {
                    fadeTexture = new Texture2D(
                        Game.GraphicsDevice,
                        RpgLibrary.RpgConstants.ScreenWidth,
                        RpgLibrary.RpgConstants.ScreenHeight);

                    Color[] colors = new Color[fadeTexture.Width * fadeTexture.Height];
                    for (int i = 0, cnt = colors.Length; i < cnt; i++)
                        colors[i] = FadeColor;

                    fadeTexture.SetData<Color>(colors);
                }

                return fadeTexture;
            }
        }

        public float Opacity
        {
            get
            {
                return opacity;
            }
        }

        public VisibilityState Visibility
        {
            get
            {
                if (opacity == 255)
                    return VisibilityState.Visible;
                if (opacity == 0)
                    return VisibilityState.Invisible;

                return VisibilityState.PartiallyVisible;
            }
        }

        public bool IsAlive { get { return true; } set { } }

        public Fade(RpgGame game, Color fadeColor)
            :base (game)
        {
            this.FadeColor = fadeColor;
            this.game = game;
            screenRect = new Rectangle(0, 0, FadeTexture.Width, FadeTexture.Height);
        }

        public Fade FadeToColor(float fadeTime)
        {
            this.opacity = 0f;
            this.fadeTime = fadeTime;
            this.fadeDirection = 1;

            return this;
        }

        public Fade FadeFromColor(float fadeTime)
        {
            this.opacity = 255f;
            this.fadeTime = fadeTime;
            this.fadeDirection = -1;

            return this;
        }

        public override void Update(GameTime gameTime)
        {
            if (fadeDirection != 0)
            {
                opacity += fadeDirection * (255 / fadeTime) * (float)gameTime.ElapsedGameTime.TotalSeconds;
                
                if (opacity > 255)
                {
                    opacity = 255;
                    fadeDirection = 0;
                }
                else if (opacity < 0)
                {
                    opacity = 0;
                    fadeDirection = 0;
                }
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            Draw(gameTime, null);
        }

        public void Draw(GameTime gameTime, Camera camera)
        {
            game.spriteBatch.Draw(
                FadeTexture, 
                new Rectangle(
                    (int)camera.Position.X, 
                    (int)camera.Position.Y, 
                    screenRect.Width, 
                    screenRect.Height),
                new Color(255,255,255, (int)opacity));

            base.Draw(gameTime);
        }
    }
}
